package tmhm.shemes;


import java.awt.Point;
import java.util.ArrayList;

import tmhm.components.*;
import tmhm.gui.GuiLabel;
import tmhm.gui.GuiLine;
import tmhm.gui.GuiScheme;


public class Counter {

    private static KMOPR KMOPR1;
    private static KMADR KMADR1;
    private static MP MP1;
    private static REG mPC;
    private static OR ORmPC;
    private static NOT NOTmPC;
    private static MicroMEM mMEM;
    
    private static IntToBools mCWbits0_23,  mCWbits24_47, mCWbits48_71, mCWbits72_95, mCWbits96_103, mCWbits104_111; 
    
    private static BoolsToInt zeroes;
    private static GuiScheme gui;

    public static GuiScheme getGui() {
        return gui;
    }

    public static void init() {
        KMOPR1 = new KMOPR();
        KMOPR1.getOut(0).setNumOfLines(8);

        KMADR1 = new KMADR();
        KMADR1.getOut(0).setNumOfLines(8);

        MP1 = new MP(4);
        MP1.getOut(0).setNumOfLines(8);
        MP1.getOut(0).setIsInt();

        mPC = new REG(1, "mPC");
        mPC.getOut(0).setNumOfLines(8);
        mPC.getOut(0).setIsInt();

        ORmPC = new OR(4);
        NOTmPC = new NOT();

        mMEM = new MicroMEM(230);


        mCWbits0_23 = new IntToBools(1, 24);
        mCWbits24_47 = new IntToBools(1, 24);
        mCWbits48_71 = new IntToBools(1, 24);
        mCWbits72_95 = new IntToBools(1, 24);
        mCWbits96_103 = new IntToBools(1, 8);
        mCWbits104_111 = new IntToBools(1, 8);
        
        
        zeroes = new BoolsToInt(8, 8);
    }

    public static void connect() {
        KMOPR1.setInputPin(0, Fetch2.NOP());
        KMOPR1.setInputPin(1, Fetch2.HALT());
        KMOPR1.setInputPin(2, Fetch2.INTD());
        KMOPR1.setInputPin(3, Fetch2.INTE());
        KMOPR1.setInputPin(4, Fetch2.TRPD());
        KMOPR1.setInputPin(5, Fetch2.TRPE());
        KMOPR1.setInputPin(6, Fetch2.LDB());
        KMOPR1.setInputPin(7, Fetch2.LDW());
        KMOPR1.setInputPin(8, Fetch2.STB());
        KMOPR1.setInputPin(9, Fetch2.STW());

        KMOPR1.setInputPin(10, Fetch2.POPB());
        KMOPR1.setInputPin(11, Fetch2.POPW());
        KMOPR1.setInputPin(12, Fetch2.PUSHB());
        KMOPR1.setInputPin(13, Fetch2.PUSHW());
        KMOPR1.setInputPin(14, Fetch2.LDIVTP());
        KMOPR1.setInputPin(15, Fetch2.STIVTP());
        KMOPR1.setInputPin(16, Fetch2.LDIMR());
        KMOPR1.setInputPin(17, Fetch2.STIMR());
        KMOPR1.setInputPin(18, Fetch2.LDSP());
        KMOPR1.setInputPin(19, Fetch2.STSP());
        KMOPR1.setInputPin(20, Fetch2.ADD());
        KMOPR1.setInputPin(21, Fetch2.SUB());
        KMOPR1.setInputPin(22, Fetch2.INC());
        KMOPR1.setInputPin(23, Fetch2.DEC());
        KMOPR1.setInputPin(24, Fetch2.AND());
        KMOPR1.setInputPin(25, Fetch2.OR());
        KMOPR1.setInputPin(26, Fetch2.XOR());
        KMOPR1.setInputPin(27, Fetch2.NOT());
        KMOPR1.setInputPin(28, Fetch2.ASR());
        KMOPR1.setInputPin(29, Fetch2.LSR());
        KMOPR1.setInputPin(30, Fetch2.ROR());
        KMOPR1.setInputPin(31, Fetch2.RORC());
        KMOPR1.setInputPin(32, Fetch2.ASL());
        KMOPR1.setInputPin(33, Fetch2.LSL());
        KMOPR1.setInputPin(34, Fetch2.ROL());
        KMOPR1.setInputPin(35, Fetch2.ROLC());
        KMOPR1.setInputPin(36, Fetch2.BEQL());
        KMOPR1.setInputPin(37, Fetch2.BNEQL());
        KMOPR1.setInputPin(38, Fetch2.BNEG());
        KMOPR1.setInputPin(39, Fetch2.BNNEG());
        KMOPR1.setInputPin(40, Fetch2.BOVF());
        KMOPR1.setInputPin(41, Fetch2.BNOVF());
        KMOPR1.setInputPin(42, Fetch2.BCAR());
        KMOPR1.setInputPin(43, Fetch2.BNCAR());
        KMOPR1.setInputPin(44, Fetch2.BGRT());
        KMOPR1.setInputPin(45, Fetch2.BGRTE());
        KMOPR1.setInputPin(46, Fetch2.BLSS());
        KMOPR1.setInputPin(47, Fetch2.BLSSE());
        KMOPR1.setInputPin(48, Fetch2.BGRTU());
        KMOPR1.setInputPin(49, Fetch2.BGRTEU());
        KMOPR1.setInputPin(50, Fetch2.BLSSU());
        KMOPR1.setInputPin(51, Fetch2.BLSSEU());
        KMOPR1.setInputPin(52, Fetch2.JMP());
        KMOPR1.setInputPin(53, Fetch2.INT());
        KMOPR1.setInputPin(54, Fetch2.JSR());
        KMOPR1.setInputPin(55, Fetch2.RTI());
        KMOPR1.setInputPin(56, Fetch2.RTS());

        KMADR1.setInputPin(0, Fetch2.regdir());
        KMADR1.setInputPin(1, Fetch2.regind());
        KMADR1.setInputPin(2, Fetch2.memdir());
        KMADR1.setInputPin(3, Fetch2.memind());
        KMADR1.setInputPin(4, Fetch2.regindpom());
        KMADR1.setInputPin(5, Fetch2.bxpom());
        KMADR1.setInputPin(6, Fetch2.pcpom());
        KMADR1.setInputPin(7, Fetch2.imm());

        MP1.setInputPin(0, mMEM.getOut(5));
        MP1.setInputPin(1, KMADR1.getOut(0));
        MP1.setInputPin(2, KMOPR1.getOut(0));
        Pin p = new Pin(0, 1);
        p.setIsInt();
        MP1.setInputPin(3, p);
        MP1.setCtrl(0, Uprav1.bradr());
        MP1.setCtrl(1, Uprav1.bropr());

        ORmPC.setInputPin(0, Uprav1.bradr());
        ORmPC.setInputPin(1, Uprav1.bropr());
        ORmPC.setInputPin(2, Uprav1.branch());
        ORmPC.setInputPin(3, Uprav1.br());
        NOTmPC.setInputPin(0, ORmPC.getOut(0));

        mPC.setInputPin(0, MP1.getOut(0));
        mPC.setPinLd(ORmPC.getOut(0));
        mPC.setPinInc(NOTmPC.getOut(0));

        mMEM.setInputPin(0, mPC.getOut(0));


        mCWbits0_23.setInputPin(0, mMEM.getOut(0));
        mCWbits24_47.setInputPin(0, mMEM.getOut(1));
        mCWbits48_71.setInputPin(0, mMEM.getOut(2));
        mCWbits72_95.setInputPin(0, mMEM.getOut(3));
        mCWbits96_103.setInputPin(0, mMEM.getOut(4));
        mCWbits104_111.setInputPin(0, mMEM.getOut(5));
        
        for (int i = 0; i < 8; i++) {
            zeroes.setInputPin(i, new Pin(false));
        }

    }

    public static void gui() {
        GuiLine line; // Pomocna promenljiva
        gui = new GuiScheme("tmhm/tmhm/images/Counter.png");

        ArrayList<ArrayList<Point>> sections;
        ArrayList<Point> points;



sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(125,81));
points.add(new Point(125,90));
sections.add(points);
line=new GuiLine(sections,Fetch2.NOP());
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(140,81));
points.add(new Point(140,90));
sections.add(points);
line=new GuiLine(sections,Fetch2.HALT());
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(219,81));
points.add(new Point(219,90));
sections.add(points);
line=new GuiLine(sections,Fetch2.RTS());
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(276,81));
points.add(new Point(276,90));
sections.add(points);
line=new GuiLine(sections,Fetch2.regdir());
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(291,81));
points.add(new Point(291,90));
sections.add(points);
line=new GuiLine(sections,Fetch2.regind());
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(370,81));
points.add(new Point(370,90));
sections.add(points);
line=new GuiLine(sections,Fetch2.imm());
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(172,139));
points.add(new Point(172,194));
sections.add(points);
line=new GuiLine(sections,KMOPR1.getOut(0));
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(323,139));
points.add(new Point(323,166));
points.add(new Point(202,166));
points.add(new Point(202,194));
sections.add(points);
line=new GuiLine(sections,KMADR1.getOut(0));
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(142,183));
points.add(new Point(142,194));
sections.add(points);
line=new GuiLine(sections,zeroes.getOut(0));
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(360,487));
points.add(new Point(360,505));
points.add(new Point(477,505));
points.add(new Point(477,175));
points.add(new Point(233,175));
points.add(new Point(233,194));
sections.add(points);
line=new GuiLine(sections,mMEM.getOut(0));
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(262,203));
points.add(new Point(255,203));
sections.add(points);
line=new GuiLine(sections,Uprav1.bradr());
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(262,222));
points.add(new Point(255,222));
sections.add(points);
line=new GuiLine(sections, Uprav1.bropr());
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(187,232));
points.add(new Point(187,269));
sections.add(points);
line=new GuiLine(sections,MP1.getOut(0));
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(112,288));
points.add(new Point(120,288));
sections.add(points);
line=new GuiLine(sections,LogicalComponent.getCPUCLK());
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(326,271));
points.add(new Point(319,271));
sections.add(points);
line=new GuiLine(sections,Uprav1.bradr());
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(318,282));
points.add(new Point(327,282));
sections.add(points);
line=new GuiLine(sections,Uprav1.bropr());
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(326,305));
points.add(new Point(319,305));
sections.add(points);
line=new GuiLine(sections,Uprav1.branch());
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(326,294));
points.add(new Point(317,294));
sections.add(points);
line=new GuiLine(sections,Uprav1.br());
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(297,288));
points.add(new Point(289,288));
sections.add(points);
points=new ArrayList<Point>();
points.add(new Point(260,297));
points.add(new Point(289,297));
points.add(new Point(289,279));
points.add(new Point(255,279));
sections.add(points);
line=new GuiLine(sections,ORmPC.getOut(0));
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(187,307));
points.add(new Point(187,345));
sections.add(points);
line=new GuiLine(sections,mPC.getOut(0));
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(113,364));
points.add(new Point(120,364));
sections.add(points);
line=new GuiLine(sections,new Pin(false));
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(422,428));
points.add(new Point(415,428));
sections.add(points);
line=new GuiLine(sections,LogicalComponent.getCPUCLK());
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(415,450));
points.add(new Point(422,450));
sections.add(points);
line=new GuiLine(sections,new Pin(true));
gui.addLine(line);


sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(86,458));
points.add(new Point(86,465));
sections.add(points);
line=new GuiLine(sections,mCWbits0_23.getOut(23));
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(225,458));
points.add(new Point(225,465));
sections.add(points);
line=new GuiLine(sections,mCWbits72_95.getOut(0));
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(259,458));
points.add(new Point(259,465));
sections.add(points);
line=new GuiLine(sections,mCWbits96_103.getOut(7));
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(304,458));
points.add(new Point(304,465));
sections.add(points);
line=new GuiLine(sections,mCWbits96_103.getOut(0));
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(338,458));
points.add(new Point(338,465));
sections.add(points);
line=new GuiLine(sections,mCWbits104_111.getOut(7));
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(383,458));
points.add(new Point(383,465));
sections.add(points);
line=new GuiLine(sections,mCWbits104_111.getOut(0));
gui.addLine(line);



sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(157,491));
points.add(new Point(157,543));
sections.add(points);
line=new GuiLine(sections,mMEM.getOut(0));
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(281,487));
points.add(new Point(281,533));
points.add(new Point(432,533));
points.add(new Point(432,543));
sections.add(points);
line=new GuiLine(sections,mMEM.getOut(4));
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(346,550));
points.add(new Point(356,550));
sections.add(points);
line=new GuiLine(sections,Exec2.START());
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(346,565));
points.add(new Point(356,565));
sections.add(points);
line=new GuiLine(sections,Bus1.hack());
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(346,580));
points.add(new Point(356,580));
sections.add(points);
line=new GuiLine(sections,Bus1.fcCPU());
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(346,610));
points.add(new Point(356,610));
sections.add(points);
line=new GuiLine(sections,Fetch3.gropr());
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(346,641));
points.add(new Point(355,641));
sections.add(points);
line=new GuiLine(sections,Fetch3.I1());
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(346,671));
points.add(new Point(355,671));
sections.add(points);
line=new GuiLine(sections,new Pin(false));
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(518,550));
points.add(new Point(508,550));
sections.add(points);
line=new GuiLine(sections,Fetch2.regdir());
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(518,580));
points.add(new Point(508,580));
sections.add(points);
line=new GuiLine(sections,Fetch2.NOP());
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(518,610));
points.add(new Point(508,610));
sections.add(points);
line=new GuiLine(sections,Exec4.brpom());
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(518,641));
points.add(new Point(508,641));
sections.add(points);
line=new GuiLine(sections,Intr1.prekid());
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(518,671));
points.add(new Point(509,671));
sections.add(points);
line=new GuiLine(sections,new Pin(false));
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(387,693));
points.add(new Point(387,678));
sections.add(points);
line=new GuiLine(sections,Uprav1.bradr());
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(417,693));
points.add(new Point(417,678));
sections.add(points);
line=new GuiLine(sections,Uprav1.bropr());
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(447,692));
points.add(new Point(447,678));
sections.add(points);
line=new GuiLine(sections,Uprav1.br());
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(187,382));
points.add(new Point(187,420));
sections.add(points);
line=new GuiLine(sections,zeroes.getOut(0));
gui.addLine(line);
sections=new ArrayList<ArrayList<Point>>();
points=new ArrayList<Point>();
points.add(new Point(477,678));
points.add(new Point(477,693));
sections.add(points);
line=new GuiLine(sections,Uprav1.branch());
gui.addLine(line);

        //LABELE:
        gui.addLabel(new GuiLabel(154, 155, KMOPR1.getOut(0)));
        gui.addLabel(new GuiLabel(305, 155, KMADR1.getOut(0)));
        gui.addLabel(new GuiLabel(389, 195, mMEM.getOut(5)));
        gui.addLabel(new GuiLabel(389, 520, mMEM.getOut(5)));
        gui.addLabel(new GuiLabel(160, 250, MP1.getOut(0)));
        gui.addLabel(new GuiLabel(160, 320, mPC.getOut(0)));
        gui.addLabel(new GuiLabel(255, 520, mMEM.getOut(4)));
        gui.addLabel(new GuiLabel(60, 520, mMEM.getOut(0)));
        gui.addLabel(new GuiLabel(102, 520, mMEM.getOut(1)));
        gui.addLabel(new GuiLabel(144, 520, mMEM.getOut(2)));
        gui.addLabel(new GuiLabel(186, 520, mMEM.getOut(3)));
        
            
    }

    
    public static Pin KMADR() {
        return KMADR1.getOut(0);
    }

    public static Pin KMOPR() {
        return KMOPR1.getOut(0);
    }

    public static Pin mPC() {
        return mPC.getOut(0);
    }


    public static REG mPCREG() {
        return mPC;
    }
    
    // moje
    
    public static IntToBools mCW0_23() {
    	return mCWbits0_23;
    }
    public static IntToBools mCW24_47() {
    	return mCWbits24_47;
    }
    public static IntToBools mCW48_71() {
    	return mCWbits48_71;
    }
    public static IntToBools mCW72_95() {
    	return mCWbits72_95;
    }
    
    public static Pin mCW96() {
        return mCWbits96_103.getOut(7);
    }

    public static Pin mCW97() {
        return mCWbits96_103.getOut(6);
    }

    public static Pin mCW98() {
        return mCWbits96_103.getOut(5);
    }

    public static Pin mCW99() {
        return mCWbits96_103.getOut(4);
    }

    public static Pin mCW100() {
        return mCWbits96_103.getOut(3);
    }

    public static Pin mCW101() {
        return mCWbits96_103.getOut(2);
    }

    public static Pin mCW102() {
        return mCWbits96_103.getOut(1);
    }

    public static Pin mCW103() {
        return mCWbits96_103.getOut(0);
    }
    
}
